#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
using ll = long long;
using T = int;
T rad(); // quick read
const int inf = 0x3f3f3f3f;
#define rf(i, n) for (int i = 1; i <= (n); ++i)
const int maxn = 5 + 3e3;
const int max_size = 5 + maxn * 4 + 200000 * 30;
const int maxp = 5 + 3e3;

struct Node {
    int up, dwn;
    Node(int a = -inf, int b = inf) { up = a, dwn = b; }
};
Node maintain(Node l, Node r) { return {max(l.up, r.up), min(l.dwn, r.dwn)}; }

struct Segtree0 {

    int tot;
    Node val[max_size];
    int ch[max_size][2];
    int new_node() { return val[++tot] = Node(), ch[tot][0] = 0, ch[tot][1] = 0, tot; }

    int update(int u, int l, int r, int i, int x) {
        if (u == 0) u = new_node();
        if (l == r) {
            val[u] = maintain(val[u], {x, x});
            return u;
        }
        int mid = l + r >> 1;
        if (i <= mid)
            ch[u][0] = update(ch[u][0], l, mid, i, x);
        else
            ch[u][1] = update(ch[u][1], mid + 1, r, i, x);
        val[u] = maintain(val[ch[u][0]], val[ch[u][1]]);
        return u;
    }
    Node ask(int u, int l, int r, int s, int t) {
        if (u == 0) return Node();
        if (s <= l && r <= t) return val[u];
        int mid = l + r >> 1;
        if (t <= mid) return ask(ch[u][0], l, mid, s, t);
        if (s > mid) return ask(ch[u][1], mid + 1, r, s, t);
        return maintain(ask(ch[u][0], l, mid, s, t), ask(ch[u][1], mid + 1, r, s, t));
    }
} seg0;

struct Segtree {
    int root[maxp << 2];
    void build(int u, int l, int r) {
        root[u] = seg0.new_node();
        if (l == r) return;
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
    }
    void update(int u, int l, int r, int p1, int p2, int x) { // (p1, p2) insert(x)
        seg0.update(root[u], 1, maxp, p2, x);
        if (l == r) return;
        int mid = l + r >> 1;
        if (p1 <= mid)
            update(u << 1, l, mid, p1, p2, x);
        else
            update(u << 1 | 1, mid + 1, r, p1, p2, x);
    }

    Node ask(int u, int l, int r, int s1, int t1, int s2, int t2) {
        if (s1 <= l && r <= t1) return seg0.ask(root[u], 1, maxp, s2, t2);
        int mid = l + r >> 1;
        if (t1 <= mid) return ask(u << 1, l, mid, s1, t1, s2, t2);
        if (s1 > mid) return ask(u << 1 | 1, mid + 1, r, s1, t1, s2, t2);
        return maintain(ask(u << 1, l, mid, s1, t1, s2, t2), ask(u << 1 | 1, mid + 1, r, s1, t1, s2, t2));
    }

} seg;

int main() {
    seg.build(1, 1, maxp);
    int n = rad(), m = rad();
    rf(i, n) {
        int l = rad(), r = rad(), x = rad();
        seg.update(1, 1, maxp, l, r, x);
    }
    int last = 0;
    rf(i, m) {
        int op = rad();
        if (op == 1) { // update
            int p1 = rad() ^ last, p2 = rad() ^ last, x = rad();
            seg.update(1, 1, maxp, p1, p2, x);
        } else {
            int l = rad() ^ last, r = rad() ^ last;
            Node tmp = seg.ask(1, 1, maxp, l, r, l, r);
            int ans = tmp.up - tmp.dwn;
            printf("%d\n", ans);
            last = ans;
        }
    }
}

T rad() {
    T back = 0;
    int ch = 0, posi = 0;
    for (; ch < '0' || ch > '9'; ch = getchar())
        posi = ch ^ '-';
    for (; ch >= '0' && ch <= '9'; ch = getchar())
        back = (back << 1) + (back << 3) + (ch & 0xf);
    return posi ? back : -back;
}

/*
3 5
2 3 1
5 6 4
4 10 5

2 2 5
2 2 6
2 2 9
1 2 3 20
2 5 14
*/